home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 117 / PC Guia 117.iso / Software / Utils / Software6 / Product2 / adblock-0.5.2.039-fx.xpi / chrome / adblock.jar / content / adblock.js < prev    next >
Encoding:
JavaScript  |  2004-07-03  |  44.4 KB  |  1,043 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Adblock for Mozilla.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Henrik Aasted Sorensen.
  18.  * Portions created by the Initial Developer are Copyright (C) 2002
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  * Henrik Aasted Sorensen
  23.  * Stefan Kinitz
  24.  * Wladimir Palant
  25.  * rue
  26.  *
  27.  * ***** END LICENSE BLOCK ***** */
  28.  
  29. // Bool: did adblock successfully load (set by adblock.xul) -- global var.
  30. var Loaded;
  31. // Bool: is adblock enabled (set by pref-observer) -- global var.
  32. var Enabled;
  33. // Bool: quickblock background-images (set by pref-observer) -- global var.
  34. var QuickblockBackground;
  35.  
  36. // binary array-search -- returns lowest-matching element if found; false otherwise
  37. // -- Requires a SORTED array
  38. //  -- note: sorting with a compareFunction defines ordering -> return: zero::unchanged, pos::first value, neg::second value
  39. function abBinSearchArray(array, searchItem) {
  40.     var low = 0;
  41.     var high = this.length-1;
  42.     var searchPoint = 0;
  43.     var match = false;
  44.     while ((high-low > 1) && !match) {
  45.         searchPoint = Math.floor((high-low)/2+low);
  46.         if (array[pos] == searchItem)
  47.             match = array[searchPoint];
  48.         else {
  49.             if (searchItem < array[curr]) high = searchPoint;
  50.             else {
  51.                 if (searchItem > array[curr]) low = searchPoint;
  52.             }
  53.         }
  54.     } 
  55.     return match;
  56. }
  57.  
  58.  
  59. // Status element drag-n-drop
  60. var abDrag = function(evt) {
  61.     clearTimeout(window.abDragCleanup);
  62.     if (!adblockStatusDrag.statusbar.abDrag) {
  63.         adblockStatusDrag.statusbar.setAttribute("abdrag", true); // css takes care of stylin'
  64.         adblockStatusDrag.statusbar.abDrag = true; }
  65.     //adblockStatusDrag.showBorders();
  66.     /*window.addEventListener("dragexit", function(evt, session) { 
  67.             if (adblockStatusDrag.statusbar.abDrag)
  68.                 adblockStatusDrag.scheduleCleanup();
  69.         }, true);*/
  70.  
  71.     // these are lost after the drop
  72.     if (!evt.target.dragLoaded) {
  73.         evt.target.dragLoaded = true;
  74.         evt.target.addEventListener("mouseup", function() { setTimeout('adblockStatusDrag.dragCleanup();',5); }, true); }
  75.     
  76.     var modEvt = { originalTarget:evt.originalTarget, target:evt.target, preventBubble:function(){} };
  77.     evt.preventBubble();
  78.     setTimeout(function(modEvt) {nsDragAndDrop.startDrag(modEvt, adblockStatusDrag);}, 50, modEvt);
  79. };
  80. var adblockStatusDrag = {
  81.     load: function() {
  82.         var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
  83.         loader.loadSubScript('chrome://global/content/nsDragAndDrop.js');
  84.         loader.loadSubScript('chrome://global/content/nsTransferable.js');
  85.         dragEnter = function(evt) { nsDragAndDrop.dragEnter(evt, adblockStatusDrag); };
  86.         dragOver = function(evt) { nsDragAndDrop.dragOver(evt, adblockStatusDrag); }; // required for drop
  87.         dragDrop = function(evt) { nsDragAndDrop.drop(evt, adblockStatusDrag); };
  88.         dragExit = function(evt) { nsDragAndDrop.dragExit(evt, adblockStatusDrag); };
  89.         dragCleanup = function() { adblockStatusDrag.dragCleanup(); };
  90.         
  91.         // adblock status-element
  92.         this.status = document.getElementById("adblock-status");
  93.         this.status.addEventListener("draggesture", abDrag, true);
  94.         
  95.         // statusbar
  96.         this.statusbar = document.getElementById("status-bar");
  97.         var child = this.statusbar.firstChild, x = 0, defaultDropArray = new Array();
  98.         while (child) {
  99.             if (child != this.status) {
  100.                 if (!child.id) {
  101.                     var newId = "statusbarpanel-noID"+x;
  102.                     while (document.getElementById(newId)) newId += "x"+x;
  103.                     child.id = newId;
  104.                     child.setAttribute("persist", new String("id" + (child.persist ? " "+child.persist : "")) );
  105.                     x++; }
  106.                 if (child.childNodes.length == 0 && document.getAnonymousNodes(child).length == 0)
  107.                     child.setAttribute("abnochildren", true);
  108.                 child.addEventListener("dragenter", dragEnter, true);
  109.                 child.addEventListener("dragover", dragOver, true);
  110.                 child.addEventListener("dragdrop", dragDrop, true);
  111.                 //child.addEventListener("dragexit", dragExit, true);
  112.             }
  113.             defaultDropArray.unshift(child.id);
  114.             child = child.nextSibling;
  115.         }
  116.         // global
  117.         window.addEventListener("dragexit", dragExit, true);
  118.         return defaultDropArray; // so our load-call (prefObserver) can Right-align against these, by default
  119.     },
  120.  
  121.     /* statusbar drag-notifier */
  122.     onDragStart: function (evt, transferData, action) {
  123.         transferData.data = new TransferData();
  124.         transferData.data.addDataForFlavour("adblock-status-id", this.status.id);
  125.     },
  126.     
  127.     /* statusbar drag-listener */
  128.     getSupportedFlavours: function () {
  129.         var flavours = new FlavourSet();
  130.         flavours.appendFlavour("adblock-status-id");
  131.         return flavours;
  132.     },
  133.     onDragEnter: function(evt, session) { /*"mouseover"*/ 
  134.         if (session.sourceNode == this.status) this.showBorders();
  135.         //logfile(unlimitedListObject(session)); 
  136.     },
  137.     onDragOver: function (evt, flavour, session) { /*"mousemove"*/
  138.         /*evt.target.setAttribute("style", "-moz-outline: #AB0000 dotted 2px !important");*/ 
  139.     },
  140.     xxcanDrop: function(evt, mDragSession) { return true; },
  141.     // whoa- there can be ABSOLUTELY NO DELAYS INLINE: no throw(), alert(), etc.
  142.     onDrop: function (evt, dropdata, session) {
  143.         this.scheduleCleanup();
  144.         var parent = this.statusbar;
  145.         var prev = evt.target;
  146.         while (prev.nodeName.toLowerCase() != "statusbarpanel") prev = prev.parentNode;
  147.         var midPointCoord = prev.boxObject.x + (prev.boxObject.width/2); // the offset + midpoint
  148.         midPointCoord += !prev.previousSibling ? (prev.boxObject.width/4) // + additional quarter-coverage for left-most panel
  149.                 : (!prev.nextSibling ? (-prev.boxObject.width/4) : 0); // - less quarter-coverage for right-most panel
  150.         if (evt.clientX < midPointCoord)
  151.             prev = prev.previousSibling;
  152.         var next = (!prev) ?
  153.                 parent.firstChild : (prev.nextSibling != this.status) ? 
  154.                         prev.nextSibling : prev.nextSibling.nextSibling;
  155.         
  156.         prevString = new Array();
  157.         for (var i=0, children=parent.childNodes; i<children.length && children[i]!=next; i++)
  158.             if (children[i].id && children[i] != this.status
  159.                     && children[i].boxObject.width != 0  // ignore undisplayed elements
  160.                     || children[i].boxObject.x+(0.75*children[i].boxObject.width) > (this.statusbar.boxObject.width/2)) // offset+.75width is over the statusbar midpoint
  161.                 prevString.push(children[i].id);
  162.         
  163.         prevString = prevString.reverse().join(",");
  164.         //adblockPrefObserver.Branch.setCharPref("statusdrop", prevString); // pref-observer will relocate element
  165.         var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  166.         var adblockBranch = "adblock.";
  167.         var Branch = prefService.getBranch(adblockBranch);
  168.         Branch.setCharPref("statusdrop", prevString); // pref-observer will relocate element
  169.         prefService.savePrefFile(null); // save the prefs to disk
  170.     },
  171.     onDragExit: function(evt, session) { /*"mouseout"*/ 
  172.         if (session.sourceNode == this.status) this.scheduleCleanup();
  173.         //logfile(unlimitedListObject(session)); 
  174.     },
  175.     showBorders: function() {
  176.         clearTimeout(window.abDragCleanup);
  177.         if (!this.statusbar.abDrag) {
  178.             this.statusbar.setAttribute("abdrag", true); // css takes care of stylin'
  179.             this.statusbar.abDrag = true; }
  180.     },
  181.     scheduleCleanup: function(evt) {
  182.         clearTimeout(window.abDragCleanup);
  183.         window.abDragCleanup = setTimeout('adblockStatusDrag.dragCleanup();',700);
  184.     },
  185.     dragCleanup: function(debug) {
  186.         this.statusbar.setAttribute("abdrag", false);
  187.         this.statusbar.abDrag = false;
  188.         //setTimeout("throw('exit: "+debug+"');", 0);
  189.     }
  190. };
  191.  
  192.  
  193. // Preferences observer object; implements nsIObserver
  194. var adblockPrefObserver = {
  195.     // Called on window-load
  196.     load: function() {
  197.         window.removeEventListener("load", abLoad, true); // remove startup-check -- only run once
  198.         
  199.         // load component
  200.         if (typeof(Components.classes["@mozilla.org/adblock;1"]) == 'undefined') {
  201.             var appShell = Components.classes["@mozilla.org/appshell/appShellService;1"].getService(Components.interfaces.nsIAppShellService);
  202.             var hiddenWnd = appShell.hiddenDOMWindow;
  203.             //wnd.setTimeout('Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript("chrome://adblock/content/component.js")', 0);
  204.             Components.classes["@mozilla.org/moz/jssubscript-loader;1"].createInstance(Components.interfaces.mozIJSSubScriptLoader).loadSubScript("chrome://adblock/content/component.js", hiddenWnd);
  205.             Loaded = true; } // we should use an array in the hidden-window to set this when *really* loaded
  206.         else Loaded = true;
  207.  
  208.         var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  209.         observerService.notifyObservers(null, "Adblock-LoadAPIConstants", null); // copy the apiConstants to the hidden-window, in case we loaded from the root-component
  210.  
  211.         window.document.AdblockQuickblocked = false;                                // initialize quickblock tag -- *before* pref-observer
  212.         window.document.addEventListener("popupshown", adblockSetContext, true);     // sets the context-menu items
  213.         window.document.addEventListener("adblock-pageblock", adblockPageBlockListener, true);     // sets the url / uri for pageblocked tabs
  214.         
  215.         // the global arrays for flashblocking -- tracks our overlay divs 
  216.         //  -- some pages don't correctly return these with the 'getElementsByTagName' method
  217.         window.flashblockOverlayArray = new Object(); // the global hash-table of of corresponding flashblock-overlays
  218.         window.flashblockCounter = 0; // global counter for the identifying the flashblock-overlayed browsers -- starts at zero, never looks back -!
  219.  
  220.         var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  221.         this.adblockBranch = "adblock.";
  222.         this.Branch = prefService.getBranch(this.adblockBranch);
  223.         
  224.         this.windowInit = false;
  225.         this.statusElement = null, this.statusText = null;
  226.         this.mainRe =     /^adblock\.(enabled|quickblock|quickblockbackground|statusdrop)/;
  227.  
  228.         var pref = prefService.getBranch(null); // preferences root node
  229.         this.pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  230.         this.pbi.addObserver(this.adblockBranch, this, true); // keep this last, in case we hit an error.
  231.         this.observe(null, null, null);
  232.     },
  233.     
  234.     // nsISupports interface implementation -- for weak-reference by pref-observer service
  235.     QueryInterface: function(iid) {
  236.         if (!iid.equals(Components.interfaces.nsISupports)
  237.                 && !iid.equals(Components.interfaces.nsISupportsWeakReference)
  238.                 && !iid.equals(Components.interfaces.nsIObserver)) {
  239.             dump("Adblock Window Pref-Observer factory object: QI unknown interface: " + iid + "\n");
  240.             throw Components.results.NS_ERROR_NO_INTERFACE; }
  241.         return this;
  242.     },
  243.     
  244.     // removes the observer-object from service -- called when the window is no longer open
  245.     removeObserver: function() {
  246.         this.pbi.removeObserver(this.adblockBranch, this);
  247.         delete this;
  248.     },
  249.     
  250.     // observer-function
  251.     /* subject: [wrapped nsISupports :: nsIPrefBranch], nsIPrefBranchInternal
  252.        topic: "changed"*/
  253.     observe: function(subject, topic, prefName) {
  254.         
  255.         // if we don't have a valid window (closed)
  256.         if ( !(typeof(document) == 'object' && document) ) {
  257.             this.removeObserver(); // remove the observer..
  258.             return; } // ..and don't continue
  259.         
  260.         // on window-init, OR a status-critical pref change
  261.         if (!this.windowInit || this.mainRe.test(prefName)) {
  262.             
  263.             /* Globals and Status-Element */
  264.             // Create status-element pointers
  265.             if (!this.windowInit) {
  266.                 this.statusElement = document.getElementById("adblock-status");
  267.                 this.statusText = document.getAnonymousNodes(this.statusElement)[1];
  268.                 this.defaultDropArray = window.adblockStatusDrag.load(); // load drag-listeners + default right-alignment
  269.             }
  270.             
  271.             // Status drag-insertion
  272.             if (!this.windowInit || prefName == "adblock.statusdrop") {
  273.                 if (this.Branch.prefHasUserValue("statusdrop"))
  274.                     var dropArray = this.Branch.getCharPref("statusdrop").split(",");
  275.                 else dropArray = this.defaultDropArray;
  276.                 //else dropArray = "statusbar-updates,progressmeter-statusbar,statusbarpanel-progress,page-theme-button,page-report-button,security-button,privacy-button,offline-status,popupIcon,statusbar-display,component-bar".split(",");
  277.                 var dropPoint = null;
  278.                 while (dropArray.length>0 && !dropPoint)
  279.                     dropPoint = document.getElementById(dropArray.shift());
  280.                 var parent = this.statusElement.parentNode;
  281.                 var next = (!dropPoint) ? 
  282.                         parent.firstChild : (dropPoint.nextSibling != this.statusElement) ? 
  283.                                 dropPoint.nextSibling : this.statusElement.nextSibling;
  284.                 
  285.                 this.statusElement.removeEventListener("draggesture", abDrag, true);
  286.                 this.statusElement.dragReload = true;
  287.                 if (next) parent.insertBefore(parent.removeChild(this.statusElement), next);
  288.                 else parent.appendChild(parent.removeChild(this.statusElement));
  289.                 this.statusElement.dragReload = false;
  290.                 this.statusElement.addEventListener("draggesture", abDrag, true);
  291.                 this.statusElement.dragLoaded = false;
  292.                 
  293.                 // we duplicate this in the statuselement's binding, now -- to catch statusbar visibility, when initially off
  294.                 //this.statusText = document.getAnonymousNodes(this.statusElement)[1]; // element is rebound on insertion
  295.                 if (this.windowInit) this.observe(null, null, "adblock.enabled"); // we have to reload the status-text
  296.             }
  297.             
  298.             // Enabled / Disabled
  299.             if (!this.windowInit || prefName == "adblock.enabled") {
  300.                 Enabled = (!this.Branch.prefHasUserValue("enabled") || this.Branch.getBoolPref("enabled")); // default:true
  301.                 if (!Loaded) { this.statusText.value = "Unloaded"; this.statusElement.setAttribute("status", "unloaded"); }
  302.                 else if (!Enabled) { this.statusText.value = "Disabled"; this.statusElement.setAttribute("status", "notlistening"); }
  303.                 else { this.statusText.value = "Adblock"; this.statusElement.setAttribute("status", "enabled"); } }
  304.     
  305.             // Quickblock
  306.             if (!this.windowInit || prefName == "adblock.quickblock") {
  307.                 if (this.Branch.prefHasUserValue("quickblock") 
  308.                         && this.Branch.getPrefType("quickblock") == Components.interfaces.nsIPrefBranch.PREF_BOOL)
  309.                     var quickLevel = this.Branch.getBoolPref("quickblock") ? "partial" : "off"; // convert old bool-type pref to new
  310.                 else quickLevel = this.Branch.prefHasUserValue("quickblock") ? this.Branch.getCharPref("quickblock") : "partial"; // default:partial
  311.                 this.statusElement.setAttribute("quickblock", quickLevel); 
  312.                 loadQuickblock(quickLevel); }
  313.             
  314.             // QuickblockBackground
  315.             if (!this.windowInit || prefName == "adblock.quickblockbackground")
  316.                 QuickblockBackground = (this.Branch.prefHasUserValue("quickblockbackground") && this.Branch.getBoolPref("quickblockbackground")); // default:false
  317.             
  318.             // window-init
  319.             if (!this.windowInit) {
  320.                 // disable conflicting key-bindings
  321.                 var conflictingKeys, adblockKeys = ["b", "a", "f", "p", "k"];
  322.                 for (var n = 0 ; n < adblockKeys.length ; n++) {
  323.                     conflictingKeys = document.getElementsByAttribute("key", adblockKeys[n]);
  324.                     for (var q = 0 ; q < conflictingKeys.length ; q++)
  325.                         if (!( /adblock/.test(conflictingKeys[q].getAttribute("id")) ) && conflictingKeys[q].hasAttribute("modifiers"))
  326.                             if (/accel/.test(conflictingKeys[q].getAttribute("modifiers")) && /shift/.test(conflictingKeys[q].getAttribute("modifiers")) )
  327.                                 conflictingKeys[q].parentNode.removeChild(conflictingKeys[q]);
  328.                 }
  329.                 
  330.                 // flag as initialized
  331.                 this.windowInit = true;
  332.             }
  333.         }
  334.         
  335.         
  336.     }
  337. };
  338.  
  339. // runs the pref-observer once, by changing a dummy-pref 
  340. //  -- called by the status-element's binding 'onconstruct' (adblock.xml)
  341. function initAdblockPrefObserver() {
  342.     try {
  343.         var prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  344.         var Branch = prefObj.getBranch("adblock.");
  345.         var tempPref = (Branch.prefHasUserValue("observer")) ? Branch.getCharPref("observer") : "-"; // default:'-'      :P
  346.  
  347.         switch (tempPref) {
  348.             case "-": 
  349.                 Branch.setCharPref("observer", "*");
  350.                 break;
  351.             case "*":
  352.                 Branch.setCharPref("observer", "-");
  353.                 break;
  354.         }
  355.     } catch(e) {}
  356. }
  357.  
  358. // toggles the adblock-enable pref -- enabling / disabling blocking
  359. function toggleAdblockEnable() {
  360.     if (!Loaded) return;
  361.     var prefObj, Branch;
  362.     
  363.     if (Enabled)
  364.         try {
  365.             prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  366.             Branch = prefObj.getBranch("adblock.");
  367.             Branch.setBoolPref("enabled", false);
  368.         } 
  369.         catch(e) { alert("Adblock could not be disabled:\n\n" + e); }
  370.     else
  371.         try {
  372.             prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  373.             Branch = prefObj.getBranch("adblock.");
  374.             Branch.setBoolPref("enabled", true);
  375.         } 
  376.         catch(e) { alert("Adblock could not be enabled:\n\n" + e); }
  377. }
  378.  
  379.  
  380. // Checks an element and its children recursively for an attribute.
  381. function adblockFindAttribute(element, name) {
  382.     if (element.hasAttribute(name)) {
  383.         return element.getAttribute(name);
  384.     }
  385.     
  386.     if (element.hasChildNodes()) {
  387.         for (var i = 0 ; i < element.childNodes.length ; i++) {
  388.             var res = adblockFindAttribute(element.childNodes[i], name);
  389.             if (res != false) 
  390.                 return res;
  391.         }
  392.     }
  393.     
  394.     return false; // Didn't find it! 
  395. }
  396.  
  397. // sets the url / uri for pageblocked tabs
  398. function adblockPageBlockListener(evt) {
  399.     var pageElementLocal = evt.target;
  400.     var browsers = window.getBrowser().browsers; // the .getBrowser method resolves tabbed vs. non-tabbed modes -- otherwise, we'd just get .browsers directly
  401.  
  402.     // contentWindow: local window  -  contentDocument: local document
  403.     for (var i = 0, match = false; i < browsers.length &! match; i++) {
  404.         try { if (browsers[i].contentDocument == pageElementLocal.ownerDocument)  match = browsers[i]; } // end loop
  405.         catch(e) {alert("Adblock: unable to access browsers[" + i + "].contentWindow:\n\n" + e);}
  406.     }
  407.     if (!match) return;
  408.     
  409.     //match.webNavigation.stop(Components.interfaces.nsIWebNavigation.STOP_ALL); // no further loading
  410.     var curHistory = match.webNavigation.sessionHistory;
  411.     var blockedURL = pageElementLocal.adblockURI.spec; // the url we blocked
  412.     
  413.     // if a different page was already loaded
  414.     if (curHistory.index == -1 || curHistory.getEntryAtIndex(curHistory.index, false).URI.spec != blockedURL) {
  415.         var ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
  416.         var newEntry = Components.classes['@mozilla.org/browser/session-history-entry;1'].createInstance(Components.interfaces.nsISHEntry);
  417.         var newURI = ioService.newURI(blockedURL, null, null);
  418.         var origIndex = curHistory.index;
  419.         var title = "Adblocked: "+pageElementLocal.adblockURI.host.replace(/^www\./, "");
  420.         newEntry.SetURI(newURI);
  421.         newEntry.SetTitle(title);
  422.         curHistory.QueryInterface(Components.interfaces.nsISHistoryInternal);
  423.         curHistory.addEntry(newEntry, true); // add a history-item for the unblocked-page
  424.         curHistory.index = origIndex++;
  425.         //alert(origIndex+" "+curHistory.index);
  426.         //match.webNavigation.gotoIndex(origIndex+1);
  427.         
  428.         //match.contentDocument.title = "Adblocked: "+title;
  429.     }
  430.     
  431.     //match.currentURI.spec = pageElementLocal.adblockURI.spec; // initialize the blocked-uri, so the urlbar displays proper on tab-switch
  432.     if (match == window.getBrowser().selectedBrowser) gURLBar.value = pageElementLocal.adblockURI.spec; // set the urlbar manually, if this is the current browser
  433. }
  434.  
  435. // sets quickblock pref -- pref-observer catches this
  436. function toggleQuickblockEnable() {
  437.     try {
  438.         var prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  439.         var Branch = prefObj.getBranch("adblock.");
  440.     } catch(e) { alert("Quickblock could not be toggled:\n\n" + e); return; }
  441.     
  442.     if (Branch.prefHasUserValue("quickblock") 
  443.             && Branch.getPrefType("quickblock") == Components.interfaces.nsIPrefBranch.PREF_BOOL) {
  444.         var quickLevel = Branch.getBoolPref("quickblock") ? "partial" : "off"; // convert old bool-type pref to new
  445.         Branch.deleteBranch("quickblock"); }
  446.     else quickLevel = Branch.prefHasUserValue("quickblock") ? Branch.getCharPref("quickblock") : "partial"; // default:partial
  447.     
  448.     var nextLevel;
  449.     switch (quickLevel) {
  450.         case "off": 
  451.             nextLevel = "partial"; 
  452.             break;
  453.         case "partial": 
  454.             nextLevel = "full"; 
  455.             break;
  456.         case "full": 
  457.             nextLevel = "off"; 
  458.             break; 
  459.     }
  460.     Branch.setCharPref("quickblock", nextLevel); // set the pref
  461. }
  462.  
  463. // loads appropriate level of quickblock -- called by pref-observer
  464. function loadQuickblock(quickLevel) {
  465.  
  466.     switch (quickLevel) {
  467.         case "full":
  468.             if (typeof(window._Quickblock) != 'undefined') break; // the listeners are already attached, from 'partial'
  469.         case "partial":
  470.             window.document.addEventListener("dblclick", adblockQuickblock, true); // disable link-clicks..
  471.             window.document.addEventListener("click", adblockQuickblock, true); // ..and again
  472.             window.document.addEventListener("mousedown", adblockQuickblock, true); // quickblock listener
  473.             break
  474.         case "off":
  475.             window.document.removeEventListener("mousedown", adblockQuickblock, true); // remove listener
  476.             window.document.removeEventListener("click", adblockQuickblock, true);
  477.             window.document.removeEventListener("dblclick", adblockQuickblock, true);
  478.             try{ 
  479.                 window.document.removeEventListener("mousemove", adblockQuickblock, true);
  480.                 window.document.removeEventListener("mouseup", adblockQuickblock, true);
  481.             } catch(e) {}
  482.             break;
  483.     }
  484.  
  485.     window._Quickblock = quickLevel; // store the level, so quickblock-listeners know what to do
  486. }
  487.  
  488. // intercepts mouse-clicks and hides the dom-elements beneath
  489. function adblockQuickblock(evt) {
  490.     var evType = evt.type, evButton = evt.button, evShift = evt.shiftKey, evCount = evt.detail;
  491.     var fullBlock = (window._Quickblock == "full") ? true : false; // bool: trap single-clicks too?
  492.     var item = evt.originalTarget;
  493.     var itemContainer = evt.target;
  494.     var deepItem = evt.explicitOriginalTarget;
  495.     var deepReplacement, deepStyle, itemTag, tagRe;
  496.     
  497.     // if quickdrag is ending (mouseup), or the event is new (mouse left the window-area while dragging)
  498.     //   ..disable quickdrag and return
  499.     if (window._Quickdrag && (evType == "mouseup" || evType == "mousedown" || (evType == "mousemove" &! evShift))) {
  500.         delete window._Quickdrag;
  501.         window.document.removeEventListener("mousemove", adblockQuickblock, true);
  502.         window.document.removeEventListener("mouseup", adblockQuickblock, true);
  503.         return;
  504.     }
  505.     
  506.     // from here on, only shifted / non-form-submission events matter -- evCount registers at max for form-submission keypresses
  507.     if (!evShift || (evType == "click" && evCount > 3)) 
  508.         return; 
  509.     
  510.     // if this is a webpage-element -- for now, all xul-elements remain unblocked (because of window-scrollbars)
  511.     if ((item != itemContainer) && (item.ownerDocument.baseURI) && (item.prefix != "xul")) {
  512.     
  513.         // if we shift-(double)clicked ( +~ drag)
  514.         if ( ((evType == "dblclick" || (evType == "click" && fullBlock) || (evType == "mousedown" && (evCount > 1 || fullBlock) ))  
  515.                 && evButton == 0)
  516.                 || evType == "mousemove" || evType == "mouseup") {
  517.             evt.preventDefault(); // prevents tripping the context-menu
  518.             evt.stopPropagation(); // prevents launching hyperlinks
  519.             evt.preventBubble(); // ditto ?
  520.             evt.preventCapture(); // double-ditto ?
  521.             
  522.             // if we didn't doubleclick
  523.             if ((evType == "click" || evType == "mousedown") && evCount < 2)
  524.                 return;
  525.     
  526.             if (evType == "mouseup") {
  527.                 window.document.removeEventListener("mousemove", adblockQuickblock, true);
  528.                 window.document.removeEventListener("mouseup", adblockQuickblock, true);
  529.                 return; } // ignore further movement, after cancelling
  530.             
  531.             if (evType != "click" && evType != "dblclick") {
  532.                 if (evType == "mousedown" &! window.Quickdrag) { // if quickdrag isn't activated, make it so
  533.                     window._Quickdrag = true;
  534.                     window.document.addEventListener("mousemove", adblockQuickblock, true);
  535.                     window.document.addEventListener("mouseup", adblockQuickblock, true);
  536.                 }
  537.                 
  538.                 if (item.tagName) itemTag = item.tagName.toLowerCase();
  539.                 else itemTag = item.nodeName.toLowerCase();
  540.                 
  541.                 // background-image removal
  542.                 if (QuickblockBackground) adblockQuickBackground(item, itemTag);
  543.                 
  544.                 // element hiding
  545.                 adblockQuickElement(deepItem, item, itemTag);
  546.             }
  547.         }
  548.  
  549.     }
  550. }
  551.  
  552. // removes background-images from an element and all parent-table elements above it
  553. //  -- for quickblock
  554. function adblockQuickBackground(item, itemTag) {
  555.     var itemTest, tableItem, tableItemLast, tableChildRe, tableRe;
  556.     var parentNode1 = false, parentNode2 = false, parentNode3 = false;
  557.     var domDocNode = Components.interfaces.nsIDOMNode.DOCUMENT_NODE;
  558.  
  559.     tableChildRe = /td|tr/;
  560.     itemTest = tableChildRe.test(itemTag);
  561.     if (!itemTest && item.parentNode) { // failed; if there's a parent
  562.         /*
  563.         parentNode1 = tableChildRe.test(item.parentNode);
  564.         if (!parentNode1 && item.parentNode.parentNode) { // failed; if there's a grandparent
  565.             parentNode2 = tableChildRe.test(item.parentNode.parentNode);
  566.             if (!parentNode2 && item.parentNode.parentNode.parentNode)
  567.                 parentNode3 = tableChildRe.test(item.parentNode.parentNode.parentNode); //failed; if there's a great-grandparent
  568.         }
  569.         */
  570.     }
  571.     if ((itemTest || parentNode1 || parentNode2 || parentNode3) && (item.nodeType != domDocNode)) {
  572.         tableItemLast = item, tableItem = item;
  573.         tableRe = new RegExp("table");
  574.         while ( ! tableRe.test(tableItemLast.nodeName.toLowerCase())) { // crawl to the tabletop :P
  575.             //tableItem.setAttribute("QuickblockTableBackground", document.defaultView.getComputedStyle(tableItem, null).getPropertyValue("background-image"));
  576.             tableItem.style.setProperty("background-image", "none", "important"); // kill parent-tableitem's background-image
  577.             if (tableItem.hasAttribute("background")) tableItem.removeAttribute("background");
  578.             if (!tableItem.parentNode || tableItem.parentNode.nodeType == domDocNode) break;
  579.             tableItemLast = tableItem, tableItem = tableItem.parentNode;
  580.         }
  581.         // kill parent-table's parent-container background-image (*whew*)
  582.         tableItem.style.setProperty("background-image", "none", "important"); 
  583.         if (tableItem.hasAttribute("background")) tableItem.removeAttribute("background");
  584.     }
  585.     else {
  586.         //if (document.defaultView.getComputedStyle(item, null).backgroundImage != "none") // <- fails
  587.         item.style.setProperty("background-image", "none", "important"); // kill parent-table-container's background-image
  588.         if (item.hasAttribute("background")) item.removeAttribute("background");
  589.     }
  590. }
  591.  
  592. // quick-hides an element
  593. function adblockQuickElement(deepItem, item, itemTag) {
  594.     var tagRe;
  595.     
  596.     if (itemTag == "area") {
  597.         disableMapArea(item); // let adblock handle area-maps..
  598.         return; // ..don't continue
  599.     }
  600.     tagRe = new RegExp("table|tbody|tr|td|div|span|form|body|html|ul|ol|dl"); // ,"i" to make case-insensitive -- removed for speed
  601.     if ( ! tagRe.test(itemTag)) { // don't hide block elements..
  602.             item.style.visibility = "hidden";
  603.     }
  604.     else { // ..rather, hide what they contain                
  605.         if (item != deepItem) { // if there's a deeper node (usually text)
  606.             if (deepItem.setAttribute) {
  607.                 deepItem.style.visibility = "hidden"; // hide directly, if possible                
  608.             }
  609.             else // text has no setAttribute-method..
  610.                 deepItem.parentNode.style.setProperty("visibility", "hidden", "important"); // ..so hide the parent
  611.         }
  612.     }
  613. }
  614.  
  615. // toggles the object-override -- ("flashblocking")
  616. function toggleObjectOverride() {
  617.     var selectedPage = document.getElementById("content").selectedBrowser;
  618.     var page = document.getElementById("content").contentDocument;
  619.     var pageElement = page.documentElement;
  620.     var flashblockPosition;
  621.     
  622.     if (typeof(page.oncontextmenu) != 'undefined') delete page.oncontextmenu; // <- thehulk.com :P
  623.     
  624.     if (pageElement) {
  625.         if (pageElement.hasAttribute("AdblockFlashblocked")) {
  626.             objectRemoveOverride(page); // removes all overrides registered in the global array
  627.             flashblockPosition = pageElement.getAttribute("flashblockPosition");
  628.             delete flashblockOverlayArray[flashblockPosition]; // remove our entry from global flashblock hashtable
  629.             pageElement.removeAttribute("flashblockPosition");
  630.             delete page.onunload;
  631.             pageElement.removeAttribute("AdblockFlashblocked");
  632.         }
  633.         else {
  634.             pageElement.setAttribute("AdblockFlashblocked", true); // tags the page as "flashblocked" :)
  635.             page.onunload = "objectRemoveOverride(this)"; // unloads flashblock on page-close -- so the global hashtable doesn't fill up
  636.             flashblockPosition = new String("smooth" + flashblockCounter); // converts the unique-index to a string for our hashtable
  637.             flashblockCounter++; // increment the unique-index counter -- to keep it unique
  638.             flashblockOverlayArray[flashblockPosition] = new Array(); // initializes the global flashblock overlay array
  639.             pageElement.setAttribute("flashblockPosition", flashblockPosition); // stores the array-position in the document-element
  640.             objCheckFrames(page, "override"); // checks frames -- adds the overrides
  641.         }
  642.     }
  643.     else 
  644.         return; // no documentElement == no flashblock
  645. }
  646.  
  647.  
  648. // catches all frames / iframes for object-overriding -- requires a page/element
  649. function objCheckFrames(page, conditional) {
  650.     var itemFrames = page.getElementsByTagName("frame");
  651.     var itemiFrames = page.getElementsByTagName("iframe");
  652.     var frame, iframe;
  653.     
  654.     if (itemFrames.length > 0)    
  655.         for (var f = 0 ; f < itemFrames.length ; f++) {
  656.             frame = itemFrames[f].contentDocument;
  657.             objCheckFrames(frame, conditional); // recursion for frames
  658.         }
  659.  
  660.     if (itemiFrames.length > 0)
  661.         for (var g = 0 ; g < itemiFrames.length ; g++) {
  662.             iframe = itemiFrames[g].contentDocument;
  663.             objCheckFrames(iframe, conditional); // recursion for iframes
  664.         }
  665.         
  666.     // if we have a valid page, override it
  667.     if (page.hasChildNodes() && page.defaultView)
  668.         switch (conditional) {
  669.             case "override":
  670.                 //alert("overriding");
  671.                 objectOverride(page); // check the page itself
  672.                 break;
  673.             /* // DEPRECATED: this whole switch is unneeded now
  674.             case "remove":
  675.                 //alert("removing");
  676.                 objectRemoveOverride(page);
  677.                 break;
  678.             */
  679.         }
  680. }
  681.  
  682. // overlays all object's / embeds with a configurable div -- requires a page/element
  683. //  -- overrides their "native" menus
  684. function objectOverride(page) {
  685.     var rawObjects = page.getElementsByTagName("object");
  686.     var objects = new Array();
  687.     var objectEmbeds = new Array();
  688.     var rawEmbeds = page.getElementsByTagName("embed");
  689.     var embeds = new Array();
  690.     var applets = page.getElementsByTagName("applet");
  691.     var possibleTags = ["objects", "object-embeds", "embeds", "applets"];
  692.     var itemArray = new Array();
  693.     var childDiv, childDivTitle;
  694.     var childTable, childTableRow, childTableData, childSpan;
  695.     var x, y;
  696.     var currentOffset, topmostFrame, flashblockPosition;
  697.     
  698.     // if we're in a frame/iframe, we'll need to get the flashblockPosition from our base document
  699.     if (page.defaultView.frameElement) {
  700.         topmostFrame = page.defaultView.frameElement;
  701.         // break out of nested frames/iframes
  702.         while (topmostFrame.ownerDocument.defaultView.frameElement)
  703.             topmostFrame = topmostFrame.ownerDocument.defaultView.frameElement;
  704.         flashblockPosition = topmostFrame.ownerDocument.documentElement.getAttribute("flashblockPosition");
  705.     }
  706.     else flashblockPosition = page.documentElement.getAttribute("flashblockPosition");
  707.     
  708.             
  709.     // for each object, get its child-embed (if it has one), since only this carries correct width / height attributes
  710.     for (var t = 0; t < rawObjects.length ; t++) {
  711.         var children = rawObjects[t].getElementsByTagName("embed");
  712.         if (children.length > 0)
  713.             for (var c = 0; c < children.length; c++)
  714.                 objectEmbeds.push(children[c]); // add child to our embed-array
  715.         else
  716.             objects.push(rawObjects[t]); // assume it's blockable if there's no child-embed
  717.     }
  718.     
  719.     // check that our embed-list doesn't contain duplicates of *OBJECT-embeds* -- (we *should* just 'pop' the array, yo)
  720.     for (var s = 0; s < rawEmbeds.length ; s++) {
  721.         // fail-safe check for parentnode -- shouldn't ever fail
  722.         if (rawEmbeds[s].parentNode)
  723.             if (rawEmbeds[s].parentNode.tagName.toLowerCase() != "object")
  724.                 embeds.push(rawEmbeds[s]); // add any non-Object-embeds to our "accepted" array
  725.     }
  726.     
  727.     // creates and adds the div-overlays for objects and raw-embeds
  728.     for (var u = 0 ; u < possibleTags.length ; u++) {
  729.         
  730.         switch (possibleTags[u]) {
  731.             case "objects":
  732.                 itemArray = objects;
  733.                 childDivTitle = "AdblockObjectDiv";
  734.                 break;
  735.             case "object-embeds":
  736.                 itemArray = objectEmbeds;
  737.                 childDivTitle = "AdblockObjectDiv";
  738.                 break;
  739.             case "embeds":
  740.                 itemArray = embeds;
  741.                 childDivTitle = "AdblockEmbedDiv";
  742.                 break;
  743.             case "applets":
  744.                 itemArray = applets;
  745.                 childDivTitle = "AdblockAppletDiv";
  746.                 break;
  747.         }
  748.         
  749.         for (var w = 0 ; w < itemArray.length; w++)
  750.             if (itemArray[w] != null && itemArray[w].style.display != "none" && itemArray[w].style.visibility != "hidden") {
  751.                 x = itemArray[w].offsetLeft;
  752.                 y = itemArray[w].offsetTop;
  753.         
  754.                 // if the item is contained by parent elements, add their position in too
  755.                 currentOffset = itemArray[w];
  756.                 while (currentOffset.offsetParent) {
  757.                     x += currentOffset.offsetParent.offsetLeft;
  758.                     y += currentOffset.offsetParent.offsetTop;
  759.                     currentOffset = currentOffset.offsetParent; // increment the conditional, for while-loop
  760.                 }
  761.                                 
  762.                 if (itemArray[w].previousSibling && itemArray[w].previousSibling.attributes
  763.                             && (
  764.                                 itemArray[w].previousSibling.hasAttribute("AdblockObjectDiv") || 
  765.                                 itemArray[w].previousSibling.hasAttribute("AdblockEmbedDiv")  ||
  766.                                 itemArray[w].previousSibling.hasAttribute("AdblockAppletDiv")
  767.                             ) 
  768.                         )
  769.                         childDiv = itemArray[w].previousSibling; // we already had an overlay-div
  770.                     else {
  771.                         childDiv = page.createElement("div"); // create our div-overlay
  772.                         childDiv.innerHTML = '<table style="width: 100%; height: 100%;"><tr valign="middle"><td ' + childDivTitle + '="true"><span  ' + childDivTitle + '="true" style="display: block; text-align: center; vertical-align: middle; background-color: #FFFFFF; color: #777788; font-family: Arial, Helvetica, Sans-serif; font-size: large; font-style: italic; font-variant: small-caps; border-color: #000099; border-width: 2pt 0pt 2pt 0pt; border-style: dashed none dashed none; padding: 2pt 0pt 2pt 0pt; overflow: hidden; clip: rect(auto auto auto auto); xtext-overflow: elipsis; width: 100%;">Flashblock</span></td></tr></table>';
  773.                         childDiv.setAttribute("width", itemArray[w].offsetWidth + "px");
  774.                         childDiv.setAttribute("height", itemArray[w].offsetHeight + "px");
  775.                         childDiv.setAttribute("style", "display: block; overflow: hidden; text-overflow: elipsis; background-color: #FFDFBF; border-color: #999999; border-width: 1px; border-style: solid; position: absolute; width: " + itemArray[w].offsetWidth + "px; height: " + itemArray[w].offsetHeight + "px; left: " + x + "px; top: " + y + "px; z-index: 900; visibility: visible;");
  776.                         childDiv.setAttribute(childDivTitle, true);
  777.                         childDiv.addEventListener("click", onOverlayClick, true);
  778.                         /* 
  779.                          * we're now dealing with child-embeds individually
  780.                          */
  781.                         itemArray[w].style.visibility = "hidden"; // hide the embedded item
  782.                         itemArray[w].parentNode.insertBefore(childDiv, itemArray[w]); // append our overlay
  783.                         flashblockOverlayArray[flashblockPosition].push(childDiv); // the global pointer, so we can remove *all* overlays later -- stupid abcnews.com
  784.                         itemArray[w]._AdblockOverlay = childDiv;
  785.                     }
  786.             }
  787.     }
  788. }
  789.  
  790.  
  791. // removes the div-overlay for all objects / embeds
  792. function objectRemoveOverride(page) {
  793.     var flashblockPosition;
  794.     var divOverlays;
  795.     var flashblockedItem;
  796.     var parentNode;
  797.     
  798.     // if we're in a frame/iframe, we'll need to get the flashblockPosition from our base document
  799.     if (page.defaultView.frameElement) {
  800.         var topmostFrame = page.defaultView.frameElement;
  801.         while (topmostFrame.ownerDocument.defaultView.frameElement)
  802.             topmostFrame = topmostFrame.ownerDocument.defaultView.frameElement;
  803.         flashblockPosition = topmostFrame.ownerDocument.documentElement.getAttribute("flashblockPosition");
  804.     }
  805.     else flashblockPosition = page.documentElement.getAttribute("flashblockPosition");
  806.     
  807.     divOverlays = flashblockOverlayArray[flashblockPosition];
  808.  
  809.     for (var u = 0 ; u < divOverlays.length ; u++) {
  810.         if (divOverlays[u].parentNode) parentNode = divOverlays[u].parentNode;
  811.         else parentNode = divOverlays[u].ownerDocument;
  812.         flashblockedItem = divOverlays[u].nextSibling;
  813.         parentNode.removeChild(divOverlays[u]); // <- don't remove until *after* we get it's 'nextSibling' -- duh!
  814.         flashblockedItem.style.visibility = "visible";
  815.     }
  816. }
  817.  
  818. // Event handler, Flashblock-Overlay has been clicked
  819. function onOverlayClick(event) {
  820.     var target = event.target;
  821.     
  822.     // break out of the overlay and get our target
  823.     while (target.nodeName.toLowerCase() != "div")
  824.         target = target.parentNode;
  825.     target = target.nextSibling;
  826.  
  827.     itemFilterDialog(false, target);
  828. }
  829.  
  830.  
  831. // reveals context menu-items as needed
  832. function adblockSetContext(evt) {
  833.     if (evt.target.id != "contentAreaContextMenu") return;
  834.  
  835.     var target = gContextMenu.target;
  836.     //var menuSeparator = document.getElementById("adblock-separator-menuitem");
  837.     //var propertyMenuItem = document.getElementById("context-metadata"); // 'Properties' element-id under mozilla 1.3.1
  838.     var frameFilter = document.getElementById("adblock-iframe-menuitem");
  839.     var frameLevel = 0;
  840.     
  841.     // iframe depth-counter
  842.     var topmostFrame = target.ownerDocument.defaultView.frameElement;
  843.     if (topmostFrame)
  844.         if (topmostFrame.nodeName.toLowerCase() == "iframe") {
  845.             frameLevel = 1; // depth-counter -- begins with current
  846.             while (topmostFrame.ownerDocument.defaultView.frameElement) {
  847.                 topmostFrame = topmostFrame.ownerDocument.defaultView.frameElement;
  848.                 if (topmostFrame.tagName.toLowerCase() == "iframe")
  849.                     frameLevel++; // only for iframes, increment the counter -- we crawl up all frames
  850.             }
  851.             if (frameLevel > 1) frameFilter.label = "Adblock iFrame (" + frameLevel + " deep)";
  852.             else frameFilter.label = "Adblock iFrame";
  853.         }
  854.     
  855.     // reveal relevant item(s)    
  856.     gContextMenu.showItem('adblock-iframe-menuitem', (frameLevel > 0));
  857.     gContextMenu.showItem('adblock-image-menuitem', (target.nodeName.toLowerCase() == "img"));
  858.     gContextMenu.showItem('adblock-maparea-menuitem', (target.nodeName.toLowerCase() == "area"));
  859.     gContextMenu.showItem('adblock-object-menuitem', (target.hasAttribute && target.hasAttribute("AdblockObjectDiv") ));
  860.     gContextMenu.showItem('adblock-embed-menuitem', (target.hasAttribute && target.hasAttribute("AdblockEmbedDiv") ));
  861.     gContextMenu.showItem('adblock-applet-menuitem', (target.hasAttribute && target.hasAttribute("AdblockAppletDiv") ));
  862.     
  863. }
  864.  
  865.  
  866. // disables a map-area, so we can click on the content beneath it
  867. function disableMapArea(areaItem) {
  868.     if (!areaItem) areaItem = gContextMenu.target;
  869.     
  870.     areaItem.setAttribute("AdblockDisabled", true);
  871.     
  872.     if (areaItem.hasAttribute("coords")) {
  873.         areaItem.setAttribute("AdblockCoords", areaItem.getAttribute("coords"));
  874.         areaItem.removeAttribute("coords");
  875.     }
  876.     //areaItem.style.display = "none"; // UNNEEDED: this has the side-effect of hiding items underneath -- removing the 'coords' is enough
  877. }
  878.  
  879. // get the target node for an overlay
  880. function getOverlayTarget(target) {
  881.     while (target.nodeName.toLowerCase() != "div")
  882.         target = target.parentNode;
  883.     target = target.nextSibling;
  884.     return target;
  885. }
  886.  
  887. // pops a filter dialog on right-click
  888. function itemFilterDialog(isFrame, targetNode) {
  889.     if (typeof(targetNode) != 'undefined' && targetNode) var node = targetNode;
  890.     else node = gContextMenu.target;
  891.     // if the target is a frame / iframe
  892.     if (typeof(isFrame) != 'undefined' && isFrame)
  893.         node = node.ownerDocument.defaultView.frameElement;
  894.     var page = node.ownerDocument; // -ownerDocument -! (ps: iframes don't register a parentNode from within them)
  895.     var data = node._AdblockData;
  896.  
  897.     // passes the target item to the dialogue via window.argument[1] -- allows the item to be refiltered on 'accept'
  898.     var dialogHandle = window.openDialog("chrome://adblock/content/addfilterdialog.xul","Add filter", "chrome,modal,centerscreen", data[0].spec, node);
  899. }
  900.  
  901. // pops a filter window for "All Block-able Items.."
  902. function filterAllDialog(filterAll) {
  903.     var currentPageElement = document.getElementById("content").contentDocument.defaultView.top;
  904.     var flashblocked = document.getElementById("content").contentDocument.documentElement.hasAttribute("AdblockFlashblocked");
  905.  
  906.     // passes the root-Element to the dialogue via window.argument[0] -- allows page to be refiltered on 'accept'
  907.     //var filterAllWindow = window.open("chrome://adblock/content/filterall.xul", "adblockableItems", "chrome,centerscreen,resizable", currentPageElement);
  908.     //filterAllWindow.focus();
  909.     window.openDialog("chrome://adblock/content/filterall.xul", "adblockableItems", "chrome,centerscreen,resizable", currentPageElement);
  910. }
  911.  
  912.  
  913. // Open the settings window.
  914. function adblockSettings() {
  915.     var settingsHandle = window.open("chrome://adblock/content/settings.xul", "adblockPreferences", "chrome,resizable,centerscreen,close=no");
  916.     settingsHandle.focus();
  917. }
  918.  
  919.  
  920.  
  921.     
  922. /*
  923.        Open flags 
  924.        #define PR_RDONLY       0x01
  925.        #define PR_WRONLY       0x02
  926.        #define PR_RDWR         0x04
  927.        #define PR_CREATE_FILE  0x08
  928.        #define PR_APPEND       0x10
  929.        #define PR_TRUNCATE     0x20
  930.        #define PR_SYNC         0x40
  931.        #define PR_EXCL         0x80
  932.     
  933.     ** File modes ....
  934.     **
  935.     ** CAVEAT: 'mode' is currently only applicable on UNIX platforms.
  936.     ** The 'mode' argument may be ignored by PR_Open on other platforms.
  937.     **
  938.     **   00400   Read by owner.
  939.     **   00200   Write by owner.
  940.     **   00100   Execute (search if a directory) by owner.
  941.     **   00040   Read by group.
  942.     **   00020   Write by group.
  943.     **   00010   Execute by group.
  944.     **   00004   Read by others.
  945.     **   00002   Write by others
  946.     **   00001   Execute by others.
  947.     **
  948.     
  949.     //init the output stream with realistic options.  420 are the file
  950.     //options.. .funny huh!  
  951.         outputStream.init( file, 0x04 | 0x08, 420, 0 );
  952.  
  953. */
  954.  
  955.  
  956. /*
  957.  * Debug-routines
  958.  */
  959.  
  960. // status message
  961. function debugmsg(str) { window.defaultStatus=str; }
  962.  
  963. // lists everything in an object -- Useful debug-function.
  964. function listObject(obj, s) {
  965.     var res = "List: " + obj + "\n";
  966.     for(var list in obj) {        
  967.         if (list.indexOf(s) != -1)
  968.             res += list + ", ";
  969.     }
  970.         
  971.     alert(res); }
  972.  
  973. // lists items in an object, 
  974. function invListObject(obj, s) {
  975.     var res = "List: " + obj + "\n";
  976.     for(var list in obj) {        
  977.         if (list.indexOf(s) == -1)
  978.             res += list + ", ";
  979.     }
  980.         
  981.     alert(res); }
  982.  
  983. // basic alerts
  984. function alertMsg1(eventX) { alert("1 :: event: " + eventX); }
  985. function alertMsg2(eventX) { alert("2 :: event: " + eventX); }
  986.  
  987. // lists everything in an object -- unlimited
  988. function unlimitedListObject(obj) {
  989.     var res = "List: " + obj + "\n\n";
  990.     for(var list in obj)    
  991.         res += list + ": " + eval("obj."+list) + "\n"; //+ " -- " + (eval("obj."+list))?(eval("obj."+list+".nodeName")):null + "\n";
  992.         
  993.     return res + "--\n\n";
  994. }
  995.  
  996. // appends a given string to unique 'logfile.txt'
  997. function logfile(logString) {
  998.     var streamOut = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  999.     var dirService = Components.classes['@mozilla.org/file/directory_service;1'].getService(Components.interfaces.nsIProperties);
  1000.     var logFile = dirService.get("UChrm", Components.interfaces.nsIFile);// lxr.mozilla.org/seamonkey/source/xpcom/io/nsAppDirectoryServiceDefs.h
  1001.     logFile.append("logfile.txt"); // "appends" the file-string to our dir file-obj
  1002.     logFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666); // uniquely name file
  1003.     
  1004.     // if the file is writable, append logString
  1005.     if (logFile.isWritable()) {
  1006.         streamOut.init(logFile, 0x02, 0x200, null);
  1007.         //streamOut.flush();
  1008.         streamOut.write(logString, logString.length);
  1009.         streamOut.close(); }
  1010. }
  1011.  
  1012. // Creates a text-listing for an item's nested node structure, n-layers deep -- very useful debug tool
  1013. function listChildNodesX(itemN, depthX) {
  1014.     if (!itemN.hasChildNodes) return null;
  1015.     if (itemN.hasChildNodes()) {
  1016.     
  1017.         var itemlengthN = itemN.childNodes.length
  1018.         var prefixcharsX = '- - ';
  1019.         var prefixstringX = ' ';
  1020.         var cnodesL = ' ';
  1021.         
  1022.         // if this is our first recursion-call, 'depthX' wont be an array yet
  1023.         if (!depthX[1])
  1024.             depthX = [0, depthX]; // define iteration counter and recursion limit
  1025.  
  1026.         // sets appropriate indentation, multiplying the prefix-string by our current depth
  1027.         for (var v = 0 ; v < depthX[0] ; v++)
  1028.             prefixstringX += prefixcharsX;
  1029.         
  1030.         cnodesL += ' :' + itemlengthN + '\n'; // prints the number of childnodes for this depth
  1031.         
  1032.         for (var w = 0 ; w < itemlengthN ; w++) {
  1033.             cnodesL += prefixstringX + w + '. ' + itemN.childNodes.item(w);
  1034.             if (itemN.childNodes.item(w).hasChildNodes()) {
  1035.                 if (depthX[0] < depthX[1]) {
  1036.                     depthX[0]++;
  1037.                     cnodesL += listChildNodesX(itemN.childNodes.item(w), depthX); }
  1038.             }
  1039.             else cnodesL += '\n';
  1040.         }
  1041.     }
  1042.     return cnodesL;
  1043. }